
#include <BFont>
#include <BPainter>
#include <BMouseEvent>
#include <BSystem>
#include <BStyle>

#include <BListWidget>
#include "member_BListItem.h"
#include "member_BListWidget.h"
#include "member_BStyle.h"

using namespace BWE;

#define member					(*(member_BListWidget*)_ptr)
#define member_allocate()		_ptr = new member_BListWidget(this)
#define member_release()		delete (member_BListWidget*)_ptr

BListWidget::BListWidget(BWidget* parent) : BScrollArea(parent)
{
	member_allocate();
	this->setAreaPolicy(Policy_Growing, Policy_Preferred);
}
BListWidget::BListWidget(const BString& title, BWidget* parent) : BScrollArea(title, parent)
{
	member_allocate();
	this->setAreaPolicy(Policy_Growing, Policy_Preferred);
}
BListWidget::~BListWidget()
{
	member_release();
}

void BListWidget::setOrientation(Orientation orientation)
{
	if (member.orientation != orientation)
	{
		member.orientation = orientation;
		this->emit(Signal_OrientationChanged, member.orientation);
	}
}
Orientation BListWidget::orientation() const
{
	return member.orientation;
}

void BListWidget::setSelectMode(SelectMode selectMode)
{
	if (member.selectMode != selectMode)
	{
		member.selectMode = selectMode;
		this->clearSelection();
		this->fresh();
	}
}
SelectMode BListWidget::selectMode() const
{
	return member.selectMode;
}

void BListWidget::setItemSpacing(int itemSpacing)
{
	if (member.itemSpacing != itemSpacing)
	{
		member.itemSpacing = itemSpacing;
		this->fresh();
	}
}
int BListWidget::itemSpacing() const
{
	return member.itemSpacing;
}

void BListWidget::setItemPolicy(Policy itemPolicy)
{
	if (member.itemPolicy != itemPolicy)
	{
		member.itemPolicy = itemPolicy;
		member.dirty = true;
		this->fresh();
	}
}
Policy BListWidget::itemPolicy() const
{
	return member.itemPolicy;
}

bool BListWidget::addItem(BListItem* item)
{
	if (item && !member.items.contain(item))
	{
		member.items.append(item);
		if (item_member(item)->list != this)
		{
			if (item_member(item)->list)
				item_member(item)->list->removeItem(item);
			item_member(item)->list = this;
		}
		if (item_member(item)->widget)
			this->addChild(item_member(item)->widget);
		member.dirty = true;
		this->fresh();
		return true;
	}
	return false;
}
BListItem* BListWidget::addItem(const BString& text)
{
	BListItem* item = new BListItem(text);
	this->addItem(item);
	return item;
}
BListItem* BListWidget::addItem(Graph graph, const BString& text)
{
	BListItem* item = new BListItem(graph, text);
	this->addItem(item);
	return item;
}
BListItem* BListWidget::addItem(BIcon* icon, const BString& text)
{
	BListItem* item = new BListItem(icon, text);
	this->addItem(item);
	return item;
}
BListItem* BListWidget::addItem(BImage* image, const BString& text)
{
	BListItem* item = new BListItem(image, text);
	this->addItem(item);
	return item;
}
BListItem* BListWidget::addItem(BWidget* widget, const BString& text)
{
	BListItem* item = new BListItem(widget, text);
	this->addItem(item);
	return item;
}

bool BListWidget::insertItem(int pos, BListItem* item)
{
	if (!item || pos < 0 || pos > member.items.size())
		return false;
	if (member.items.contain(item))
	{
		int index = member.items.index(item);
		return member.items.move(index, pos);
		return true;
	}
	member.items.insert(pos, item);
	if (item_member(item)->list != this)
	{
		if (item_member(item)->list)
			item_member(item)->list->removeItem(item);
		item_member(item)->list = this;
	}
	member.dirty = true;
	this->emit(Signal_ItemInserted, item);
	this->fresh();
	return true;
}
BListItem* BListWidget::insertItem(int pos, const BString& text)
{
	if (pos < 0 || pos > member.items.size())
		return 0;
	BListItemHolder item = new BListItem(text);
	if (insertItem(pos, item))
		return item;
	return 0;
}
BListItem* BListWidget::insertItem(int pos, Graph graph, const BString& text)
{
	if (pos < 0 || pos > member.items.size())
		return 0;
	BListItemHolder item = new BListItem(graph, text);
	if (insertItem(pos, item))
		return item;
	return 0;
}
BListItem* BListWidget::insertItem(int pos, BIcon* icon, const BString& text)
{
	if (pos < 0 || pos > member.items.size())
		return 0;
	BListItemHolder item = new BListItem(icon, text);
	if (insertItem(pos, item))
		return item;
	return 0;
}
BListItem* BListWidget::insertItem(int pos, BImage* image, const BString& text)
{
	if (pos < 0 || pos > member.items.size())
		return 0;
	BListItemHolder item = new BListItem(image, text);
	if (insertItem(pos, item))
		return item;
	return 0;
}
BListItem* BListWidget::insertItem(int pos, BWidget* widget, const BString& text)
{
	if (pos < 0 || pos > member.items.size())
		return 0;
	BListItemHolder item = new BListItem(widget, text);
	if (insertItem(pos, item))
		return item;
	return 0;
}

bool BListWidget::removeItem(int index)
{
	if (BListItem* item = member.items(index))
	{
		if (member.hoveredItem == item)
		{
			member.hoveredItem = 0;
			emit(Signal_ItemHovered);
			this->fresh();
		}
		item_member(item)->list = 0;
		if (member.selectedItems.remove(item))
		{
			item_member(item)->selected = false;
			this->emit(Signal_ItemSelected, item);
		}
		if (item_member(item)->widget)
			this->removeChild(item_member(item)->widget);
		BHolder<BListItem> holder(item);
		member.items.remove(index);
		member.showBegin = -1;
		member.showEnd = -1;
		member.dirty = true;
		this->emit(Signal_ItemRemoved, item);
		this->fresh();
		return true;
	}
	return false;
}
bool BListWidget::removeItem(BListItem* item)
{
	if (!item)
		return false;
	if (item_member(item)->list != this)
		return false;
	if (member.hoveredItem == item)
	{
		member.hoveredItem = 0;
		emit(Signal_ItemHovered);
		this->fresh();
	}
	item_member(item)->list = 0;
	if (member.selectedItems.remove(item))
	{
		BListItem* item0 = member.selectedItems.at(0);
		item_member(item)->selected = false;
		this->emit(Signal_ItemSelected, item);
	}
	if (item_member(item)->widget)
		this->removeChild(item_member(item)->widget);
	BHolder<BListItem> holder(item);
	member.items.remove(item);
	member.showBegin = -1;
	member.showEnd = -1;
	member.dirty = true;
	this->emit(Signal_ItemRemoved, item);
	this->fresh();
	return true;
}
bool BListWidget::removeItem(const BString& text)
{
	BListItem* item = this->item(text);
	return removeItem(item);
}

void BListWidget::clearItems()
{
	if (member.items.size())
	{
		clearSelection();
		if (BListItem* item = member.hoveredItem)
		{
			member.hoveredItem = 0;
			emit(Signal_ItemHovered, item);
		}
		while (BListItem* item = member.items.last())
		{
			removeItem(item);
		}
		member.showBegin = -1;
		member.showEnd = -1;
		member.dirty = true;
		this->emit(Signal_Clear);
		this->fresh();
	}
}

bool BListWidget::containItem(const BListItem* item) const
{
	return member.items.contain(item);
}
bool BListWidget::containItem(const BString& text) const
{
	for (int i = 0; i < member.items.size(); i++)
	{
		BListItem* item = member.items[i];
		if (item->text() == text)
			return true;
	}
	return false;
}

int BListWidget::itemIndex(const BListItem* item) const
{
	return member.items.index(item);
}
int BListWidget::itemIndex(const BString& text) const
{
	for (auto it = member.items.begin(); it.valid(); ++it)
	{
		BListItem* item = *it;
		if (item->text() == text)
			return it.index();
	}
	return -1;
}

int BListWidget::spaceAt(const BPoint& point) const
{
	if (member.items.empty())
		return 0;
	if (member.orientation == Orientation_Vertical)
	{
		for (auto it = member.items.begin(); it.valid(); ++it)
		{
			BListItem* item = *it;
			if (point.y() < item_member(item)->ia_area.top())
				return it.index();
		}
	}
	if (member.orientation == Orientation_Horizontal)
	{
		for (auto it = member.items.begin(); it.valid(); ++it)
		{
			BListItem* item = *it;
			if (point.x() < item_member(item)->ia_area.left())
				return it.index();
		}
	}
	return member.items.size();
}
BRect BListWidget::spaceRect(int index) const
{
	const BRect& area = this->area();
	if (BListItem* item = member.items.at(index))
	{
		if (member.orientation == Orientation_Vertical)
		{
			BRect rect = item_member(item)->ia_area;
			rect.top() -= member.itemSpacing;
			rect.bottom() = rect.top() + member.itemSpacing;
			rect.left() = area.left();
			rect.right() = area.right();
			return rect;
		}
		if (member.orientation == Orientation_Horizontal)
		{
			BRect rect = item_member(item)->ia_area;
			rect.left() -= member.itemSpacing;
			rect.right() = rect.left() + member.itemSpacing;
			rect.top() = area.top();
			rect.bottom() = area.bottom();
			return rect;
		}
	}
	else
	{
		if (member.orientation == Orientation_Vertical)
		{
			BRect rect = area;
			rect.bottom() = rect.top() + member.itemSpacing;
			return rect;
		}
		if (member.orientation == Orientation_Horizontal)
		{
			BRect rect = area;
			rect.right() = rect.left() + member.itemSpacing;
			return rect;
		}
	}
	return area;
}

int BListWidget::itemCount() const
{
	return member.items.size();
}
BListItem* BListWidget::item(int index)
{
	return member.items(index);
}
const BListItem* BListWidget::item(int index) const
{
	return member.items(index);
}

BListItem* BListWidget::item(const BString& text)
{
	for (auto item : member.items)
	{
		if (item->text() == text)
			return item;
	}
	return 0;
}
const BListItem* BListWidget::item(const BString& text) const
{
	for (auto item : member.items)
	{
		if (item->text() == text)
			return item;
	}
	return 0;
}

BListItem* BListWidget::itemAt(const BPoint& point)
{
	if (member.items.empty())
		return 0;
	if (member.showBegin < 0)
		return 0;
	const BRect& crect = this->centerRect();
	BPoint offset = this->area().pos();
	for (int i = member.showBegin; i <= member.showEnd; i++)
	{
		BListItem* item = member.items[i];
		if (!item_member(item)->visible)
			continue;
		BRect rect(item_member(item)->pos + offset, item_member(item)->size);
		rect.right() = crect.right();
		if (rect.contain(point))
			return item;
	}
	return 0;
}
const BListItem* BListWidget::itemAt(const BPoint& point) const
{
	if (member.items.empty())
		return 0;
	if (member.showBegin < 0)
		return 0;
	BPoint offset = this->area().pos();
	for (int i = member.showBegin; i <= member.showEnd; i++)
	{
		BListItem* item = member.items[i];
		if (!item_member(item)->visible)
			continue;
		BRect rect(item_member(item)->pos + offset, item_member(item)->size);
		if (rect.contain(point))
			return item;
	}
	return 0;
}

BListItem* BListWidget::itemOfName(const BString& name)
{
	if (name.empty())
		return 0;
	for (int i = 0; i < member.items.size(); i++)
	{
		BListItem* item = member.items[i];
		if (item->name() == name)
		{
			return item;
		}
	}
	return 0;
}
const BListItem* BListWidget::itemOfName(const BString& name) const
{
	if (name.empty())
		return 0;
	for (int i = 0; i < member.items.size(); i++)
	{
		const BListItem* item = member.items[i];
		if (item->name() == name)
		{
			return item;
		}
	}
	return 0;
}

BListItem* BListWidget::itemOfAsset(const BValue& asset)
{
	if (asset.empty())
		return 0;
	for (int i = 0; i < member.items.size(); i++)
	{
		BListItem* item = member.items[i];
		if (item->asset() == asset)
		{
			return item;
		}
	}
	return 0;
}
const BListItem* BListWidget::itemOfAsset(const BValue& asset) const
{
	if (asset.empty())
		return 0;
	for (int i = 0; i < member.items.size(); i++)
	{
		const BListItem* item = member.items[i];
		if (item->asset() == asset)
		{
			return item;
		}
	}
	return 0;
}

BListItem* BListWidget::itemOfWidget(const BWidget* widget)
{
	if (!widget)
		return 0;
	for (int i = 0; i < member.items.size(); i++)
	{
		BListItem* item = member.items[i];
		if (item->widget() == widget)
		{
			return item;
		}
	}
	return 0;
}
const BListItem* BListWidget::itemOfWidget(const BWidget* widget) const
{
	if (!widget)
		return 0;
	for (int i = 0; i < member.items.size(); i++)
	{
		const BListItem* item = member.items[i];
		if (item->widget() == widget)
		{
			return item;
		}
	}
	return 0;
}

bool BListWidget::setItemSelected(BListItem* item, bool selected)
{
	if (!item)
		return false;
	if (selected)
	{
		if (!member.selectedItems.contain(item))
		{
			if (member.selectMode & Select_Single)
				clearSelection();
			member.selectedItems.append(item);
			item_member(item)->selected = true;
			emit(Signal_ItemSelected, item);
			emit(Signal_SelectionChanged, member.selectedItems.size());
			this->fresh();
		}
	}
	else
	{
		if (member.selectedItems.remove(item))
		{
			item_member(item)->selected = false;
			emit(Signal_ItemSelected, item);
			emit(Signal_SelectionChanged, member.selectedItems.size());
			this->fresh();
		}
	}
	return true;
}

bool BListWidget::setSelection(BListItem* selectedItem)
{
	bool selectionChanged = false;
	for (int i = 0; i < member.selectedItems.size(); i++)
	{
		BListItem* item = member.selectedItems[i];
		if (selectedItem != item)
		{
			item_member(item)->selected = false;
			member.selectedItems.remove(i--);
			emit(Signal_ItemSelected, item);
			selectionChanged = true;
		}
	}
	if (!member.selectedItems.contain(selectedItem))
	{
		item_member(selectedItem)->selected = true;
		member.selectedItems.append(selectedItem);
		emit(Signal_ItemSelected, selectedItem);
		selectionChanged = true;
	}
	if (selectionChanged)
	{
		emit(Signal_SelectionChanged, member.selectedItems.size());
		this->fresh();
		return true;
	}
	return false;
}
bool BListWidget::setSelection(const BListItemArray& selection)
{
	bool selectionChanged = false;
	for (int i = 0; i < member.selectedItems.size(); i++)
	{
		BListItem* item = member.selectedItems[i];
		if (!selection.contain(item))
		{
			item_member(item)->selected = false;
			member.selectedItems.remove(i--);
			emit(Signal_ItemSelected, item);
			selectionChanged = true;
		}
	}
	for (int i = 0; i < selection.size(); i++)
	{
		BListItem* item = selection[i];
		if (!member.selectedItems.contain(item))
		{
			item_member(item)->selected = true;
			member.selectedItems.append(item);
			emit(Signal_ItemSelected, item);
			selectionChanged = true;
		}
	}
	member.selectedItems = selection;
	if (selectionChanged)
	{
		emit(Signal_SelectionChanged, member.selectedItems.size());
		this->fresh();
		return true;
	}
	return false;
}
const BListItemArray& BListWidget::selection() const
{
	return member.selectedItems;
}

int BListWidget::selectedItemCount() const
{
	return member.selectedItems.size();
}
BListItem* BListWidget::selectedItem(int index)
{
	return member.selectedItems(index);
}
const BListItem* BListWidget::selectedItem(int index) const
{
	return member.selectedItems(index);
}

bool BListWidget::clearSelection()
{
	if (member.selectedItems.size())
	{
		while (BListItem* item = member.selectedItems.last())
		{
			item_member(item)->selected = false;
			member.selectedItems -= item;
			emit(Signal_ItemSelected, item);
		}
		emit(Signal_SelectionChanged, 0);
		this->fresh();
	}
	return true;
}

bool BListWidget::scrollToItem(BListItem* item, Align align)
{
	if (!item || item_member(item)->list != this)
		return false;
	if (member.dirty)
	{
		member.freshArea();
	}
	return scrollToRect(item->rect());
}
bool BListWidget::sortItems(int dir)
{
	if (dir == 0)
		return false;
	while (1)
	{
		bool changed = false;
		for (auto it = member.items.begin(); it.index() < member.items.size() - 1; ++it)
		{
			auto next = it.next();
			BListItem* item0 = *it;
			BListItem* item1 = *it.next();
			if (dir > 0 && item0->text() > item1->text())
			{
				member.items.swap(it, next);
				changed = true;
			}
			if (dir < 0 && item0->text() < item1->text())
			{
				member.items.swap(it, next);
				changed = true;
			}
		}
		if (!changed)
			break;
	}
	return true;
}

BSize BListWidget::sizeHint() const
{
	if (member.dirty)
	{
		member.dirty = false;
		member.dirtyVisual = true;
		member.freshArea();
	}
	return BScrollArea::sizeHint();
}

bool BListWidget::query(const BString& text, BValue& value) const
{
	if (text == "visual-items")
	{
		BListItemArray& items = value.fill<BListItemArray>();
		items.reset();
		for (auto it = member.items.seek(member.showBegin); it.index() <= member.showEnd; ++it)
		{
			items.append(it->ptr());
		}
		return true;
	}
	return BScrollArea::query(text, value);
}

void BListWidget::scrolling(Orientation orientation)
{
	member.dirtyVisual = true;
	this->fresh();
	BScrollArea::scrolling(orientation);
}

void BListWidget::styleEvent(const BEvent& event)
{
	BScrollArea::styleEvent(event);
	const BStyle* style = this->realStyle();

	member.itemStyle = 0;

	style_member(style)->assign(Value_ItemSpacing, member.itemSpacing);
	style_member(style)->assign(Value_Orientation, member.orientation);

	if (const BStyle* itemStyle = style->annex("item"))
	{
		member.itemStyle = itemStyle;

		const BValue& itemSpacingValue = itemStyle->value(Value_ItemSpacing);
		if (itemSpacingValue.valid())
			member.itemSpacing = itemSpacingValue;

		const BValue& alignValue = itemStyle->value(Value_Align);
		if (alignValue.valid())
			member.itemAlign = alignValue;

		const BValue& itemWidthValue = itemStyle->value(Value_Width);
		if (itemWidthValue.valid())
			member.itemSize.width() = itemWidthValue;

		const BValue& itemHeightValue = itemStyle->value(Value_Height);
		if (itemHeightValue.valid())
			member.itemSize.height() = itemHeightValue;

	}

	for (int i = 0; i < member.items.size(); i++)
	{
		BListItem* item = member.items[i];
		item_member(item)->dirty = true;
		item_member(item)->dirtyStyle = true;
	}
	member.dirty = true;
	this->fresh();
}
void BListWidget::freshEvent(const BEvent& event)
{
	if (member.dirty)
	{
		member.dirty = false;
		member.dirtyVisual = true;
		member.freshArea();
	}
	if (member.dirtyVisual)
	{
		member.dirtyVisual = false;
		member.freshVisualItems();
	}
	BScrollArea::freshEvent(event);
}
void BListWidget::paintEvent(const BEvent& event)
{
	BScrollArea::paintEvent(event);

	const BRect& crect = this->centerRect();
	const BPoint& offset = this->offset();

	BPainter painter(this);
	painter.setClip(crect);
	State state = painter.state();
	if (member.showBegin >= 0)
	{
		for (int i = member.showBegin; i <= member.showEnd; i++)
		{
			const BListItem* item = member.items[i];
			if (!item_member(item)->visible)
				continue;
			State itemState = state;
			if (item_member(item)->checked)
				itemState = State_Checked;
			if (!item->enabled())
				itemState = State_Disable;
			if (member.hoveredItem == item)
			{
				if (member.pressed)
					itemState |= State_Pressed;
				else
					itemState |= State_Hovered;
			}
			else if (member.selectedItems.contain(item))
			{
				itemState |= State_Selected;
			}

			painter.pushMatrix();
			painter.translate(item_member(item)->pos + offset);
			//painter.setClip(item_member(item)->rect() & crect);
			painter.setStyle(item_member(item)->realStyle);
			item_member(item)->drawBackground(painter, itemState);
			if (item_member(item)->margin.valid())
				item_member(item)->drawMargin(painter, itemState);
			if (item_member(item)->border > 0)
				item_member(item)->drawBorder(painter, itemState);
			item_member(item)->drawContent(painter, itemState);
			painter.popMatrix();

		}
	}
	painter.setClip(this->size());
}

void BListWidget::mouseEnterEvent(const BMouseEvent& mouseEvent)
{
	if (member.hoveredItem)
	{
		member.hoveredItem = 0;
		emit(Signal_ItemHovered);
		this->fresh();
	}
	BScrollArea::mouseEnterEvent(mouseEvent);
}
void BListWidget::mouseLeaveEvent(const BMouseEvent& mouseEvent)
{
	if (member.hoveredItem)
	{
		member.hoveredItem = 0;
		emit(Signal_ItemHovered);
		this->fresh();
	}
	BScrollArea::mouseLeaveEvent(mouseEvent);
}

void BListWidget::mousePressEvent(const BMouseEvent& mouseEvent)
{
	const BPoint& pos = mouseEvent.pos();
	if (member.hoveredItem)
	{
		member.pressed = true;
		this->fresh();
	}
	if (member.selectMode & Select_Multiple)
	{
		BListItem* item = member.hoveredItem;
		if (mouseEvent.keyState(Key_Ctrl))
		{
			setItemSelected(item, !item_member(item)->selected);
		}
		else if (mouseEvent.keyState(Key_Shift))
		{
			if (member.selectedItems.empty())
			{
				setItemSelected(item, true);
			}
			else
			{
				if (item)
				{
					BListItem* firstItem = member.selectedItems.first();
					int index0 = member.items.index(firstItem);
					int index1 = member.items.index(item);
					int min = bMin(index0, index1);
					int max = bMax(index0, index1);
					for (int i = 0; i < member.selectedItems.size(); i++)
					{
						BListItem* sitem = member.selectedItems[i];
						int index = member.items.index(sitem);
						if (index < min || index > max)
						{
							member.selectedItems.remove(i--);
							item_member(sitem)->selected = false;
							emit(Signal_ItemSelected, sitem);
						}
					}
					if (index0 < index1)
					{
						for (int i = index0 + 1; i <= index1; i++)
						{
							BListItem* sitem = member.items[i];
							member.selectedItems.append(sitem);
							item_member(sitem)->selected = true;
							emit(Signal_ItemSelected, sitem);
						}
					}
					else
					{
						for (int i = index0 - 1; i >= index1; i--)
						{
							BListItem* sitem = member.items[i];
							member.selectedItems.append(sitem);
							item_member(sitem)->selected = true;
							emit(Signal_ItemSelected, sitem);
						}
					}
				}
				emit(Signal_SelectionChanged, member.selectedItems.size());
				this->fresh();
			}
		}
		else
		{
			if (item)
			{
				for (int i = 0; i < member.selectedItems.size(); i++)
				{
					BListItem* sitem = member.selectedItems[i];
					if (sitem != item)
					{
						member.selectedItems.remove(i--);
						item_member(sitem)->selected = false;
						emit(Signal_ItemSelected, sitem);
					}
				}
				if (member.selectedItems.empty())
				{
					member.selectedItems.append(item);
					item_member(item)->selected = true;
					emit(Signal_ItemSelected, item);
				}
				emit(Signal_SelectionChanged, member.selectedItems.size());
				this->fresh();
			}
			else
			{
				this->clearSelection();
			}
		}
		return;
	}
	if (member.selectMode & Select_Single)
	{
		BListItem* item = member.hoveredItem;
		if (item)
		{
			for (int i = 0; i < member.selectedItems.size(); i++)
			{
				BListItem* sitem = member.selectedItems[i];
				if (sitem != item)
				{
					member.selectedItems.remove(i--);
					item_member(sitem)->selected = false;
					emit(Signal_ItemSelected, sitem);
				}
			}
			if (member.selectedItems.empty())
			{
				member.selectedItems.append(item);
				item_member(item)->selected = true;
				emit(Signal_ItemSelected, item);
			}
			emit(Signal_SelectionChanged, member.selectedItems.size());
			this->fresh();
		}
		else
		{
			clearSelection();
		}
	}
	BScrollArea::mousePressEvent(mouseEvent);
}
void BListWidget::mouseReleaseEvent(const BMouseEvent& mouseEvent)
{
	if (member.pressed)
	{
		member.pressed = 0;
		this->fresh();
	}
	BScrollArea::mouseReleaseEvent(mouseEvent);
}
void BListWidget::mouseMoveEvent(const BMouseEvent& mouseEvent)
{
	const BPoint& pos = mouseEvent.pos();
	BListItem* hoveredItem = this->itemAt(pos);
	if (member.hoveredItem != hoveredItem)
	{
		member.hoveredItem = hoveredItem;
		emit(Signal_ItemHovered, hoveredItem);
		this->fresh();
	}
	BScrollArea::mouseMoveEvent(mouseEvent);
}

void BListWidget::mouseClickEvent(const BMouseEvent& mouseEvent)
{
	if (mouseEvent.button() == Button_Left)
	{
		emit(Signal_ItemClicked, member.hoveredItem);
	}
	if (mouseEvent.button() == Button_Right)
	{
		emit(Signal_ItemRightClicked, member.hoveredItem);
	}
	BScrollArea::mouseClickEvent(mouseEvent);
}
void BListWidget::mouseDoubleClickEvent(const BMouseEvent& mouseEvent)
{
	if (mouseEvent.button() == Button_Left)
	{
		if (member.hoveredItem)
		{
			emit(Signal_ItemDoubleClicked, member.hoveredItem);
		}
	}
	BScrollArea::mouseDoubleClickEvent(mouseEvent);
}

